﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.Unity;
using Infrastructure.Aspect.Extensions;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace S3System.InternalHost
{
    public class UnityServiceHostFactory:  global::System.ServiceModel.Activation.ServiceHostFactory
    {
        public IUnityContainer ContainerService { get; set; }
        public UnityServiceHostFactory()
        {
            try
            {
                this.ContainerService = System.Web.HttpContext.Current.Application["ContainerService"] as IUnityContainer;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            UnityServiceHost host = null;
            var att = Attribute.GetCustomAttribute(serviceType, typeof(ServiceBehaviorAttribute)) as ServiceBehaviorAttribute;
            if (att != null)
            {
                switch (att.InstanceContextMode)
                {
                    case InstanceContextMode.Single:
                        host = new UnityServiceHost(this.ContainerService.Resolve(serviceType), baseAddresses);
                        break;
                    default:
                        host = new UnityServiceHost(serviceType, baseAddresses);
                        host.Container = this.ContainerService;
                        break;
                }
            }
            else
            {
                host = new UnityServiceHost(serviceType, baseAddresses);
                host.Container = this.ContainerService;
            }
            foreach (var endpoint in host.Description.Endpoints)
            {
                if (endpoint.Contract.Name == "IMetadataExchange")
                {
                    continue;
                }
                foreach (OperationDescription operation in endpoint.Contract.Operations)
                {
                    OperationBehaviorAttribute attribute = operation.Behaviors.Find<OperationBehaviorAttribute>();
                    attribute.Impersonation = ImpersonationOption.Required;
                    //operation.Behaviors.Add(new Infrastructure.Services.Behaviors.SecurityLogOpeBehavior());
                }
            }
            return host;

        }    
  
    }
}